package com.zndroid.netmonitor.monitor.impl;

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.Log;

import androidx.annotation.NonNull;

import com.zndroid.netmonitor.NetType;
import com.zndroid.netmonitor.monitor.IMPL;
import com.zndroid.netmonitor.monitor.INetChangeCallBack;
import com.zndroid.netmonitor.monitor.Util;

import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * API <=20 采用广播的形式实现
 * */
public class MonitorImpl implements IMPL {

    private WeakReference<Context> context;
    private final Util util;

    private final @NonNull NetStatusBroadcastReceiver netStatusBroadcastReceiver;
    private final @NonNull
    INetChangeCallBack netChangeCallBack;

    private PhoneStateListener mPhoneStateListener;

    private final AtomicBoolean isReg = new AtomicBoolean(false);

    public MonitorImpl(@NonNull INetChangeCallBack netChangeCallBack) {
        this.netChangeCallBack = netChangeCallBack;
        util = new Util();
        netStatusBroadcastReceiver = new NetStatusBroadcastReceiver();
    }

    @Override
    public void startMonitor(@NonNull Context context) {
        if (isReg.get()) return;//防止重复调用
        Log.d(TAG,  "MonitorImpl impl...");

        this.context = new WeakReference<>(context);

        if (!util.isNetworkAvailable(context))
            netChangeCallBack.onNetConnected(false, NetType.NET_NONE);

        monitorWifiWithSignal(context);
        monitorPhoneSignal(context);

        isReg.set(true);
    }

    @Override
    public void stopMonitor() {
        if (context.get() != null && isReg.getAndSet(false)) {
            Log.d(TAG, "NetWorkMonitor will be stop...");

            stopMonitorWifiWithSignal();
            stopMonitorPhoneSignal();
        }
    }

    private void monitorWifiWithSignal(@NonNull Context context) {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        intentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
        context.registerReceiver(netStatusBroadcastReceiver, intentFilter);
    }

    /**
     * 手机信号强度监听
     * */
    @SuppressLint("MissingPermission")
    private void monitorPhoneSignal(@NonNull Context context) {
        mPhoneStateListener = new PhoneStateListener() {
            @Override
            public void onSignalStrengthsChanged(SignalStrength signalStrength) {
                if (util.getNetType(context).contentEquals(NetType.NET_WIFI)) return;

                TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
                int phoneStrengthLevel;

                //2G,3G不做处理，摒弃，监听4G，5G的话，手机版本也不至于低于API 20
                if (mTelephonyManager.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE) {
                    String[] params = signalStrength.toString().split(" ");
                    int lteDBM = Integer.parseInt(params[9]);
                    // 信号强度自定义：>-75dbm 算极好；-85~-75 算好；-95~-85 算一般；-100~-95 算差；<-100 算无信号
                    if (lteDBM >= -75) {
                        phoneStrengthLevel = 4;
                    } else if (lteDBM >= -85) {
                        phoneStrengthLevel = 3;
                    } else if (lteDBM >= -95) {
                        phoneStrengthLevel = 2;
                    } else if (lteDBM >= -100) {
                        phoneStrengthLevel = 1;
                    } else {
                        phoneStrengthLevel = 0;
                    }
                } else phoneStrengthLevel = 0;

                netChangeCallBack.onNetChanged(util.isNetworkAvailable(context), util.getNetType(context), phoneStrengthLevel);
            }
        };

        if (util.hasSimCard(context)) {
            TelephonyManager telephonyManager = (TelephonyManager) this.context.get().getSystemService(Context.TELEPHONY_SERVICE);
            telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
        }
    }

    private void stopMonitorWifiWithSignal() {
        if (null != context.get())
            this.context.get().unregisterReceiver(netStatusBroadcastReceiver);
    }

    private void stopMonitorPhoneSignal() {
        if (null != context.get()) {
            TelephonyManager telephonyManager = (TelephonyManager) this.context.get().getSystemService(Context.TELEPHONY_SERVICE);
            telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
        }
    }

    public class NetStatusBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            netChangeCallBack.onNetConnected(util.isNetworkAvailable(context), util.getNetType(context));

            if (util.isWifiConnected(context)) {
                WifiManager wifiManager = (WifiManager)context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
                int si = WifiManager.calculateSignalLevel(wifiManager.getConnectionInfo().getRssi(), 5);
                netChangeCallBack.onNetChanged(util.isNetworkAvailable(context), util.getNetType(context), si);
            }

        }
    }
}
